import { CreepAbilityHelper } from "utils/creep/CreepAbilityHelper";
import { BodySetup } from "utils/creep/CreepSetup";
import { UtilsHelper } from "utils/position/UtilsHelper";
import { BattleStrategy } from "./BattleStrategy";
import { RoomObjectSample } from "algorithm/Cluster/Sample/RoomObjectSample";
import { DBScan } from "algorithm/Cluster/DBScan";
import { CacheDataStructure } from "GameLoop/WorldState/PollingStation/PollingTasks/RoomItem/CacheStructure";
import { DefendStrategy } from "./DefendStrategy";
import { getRoleConfig } from "utils/constants/bodyconstant";

/**
 * 当heal的body大于攻击的body数量时，就需要更换算法。用换伤来计算对应的爬
 */
export class WarStrategy
{
    private static battelstrategy = new BattleStrategy();
    private static defendstrategy = new DefendStrategy();
    public static createPlan(room:Required<Room>,enemys:Creep[],maxBoost:number=3):IWarPlan|undefined
    {
        
        const stats = this.getEnemystatus(enemys);
        return this.createPlanOfBattle(room,stats,maxBoost);
    }

     /**
     * 拆建筑
     */ 
    public static createPlanOfDestoryStructure(room:Required<Room> ):IWarPlan|undefined
    {
        const body = getRoleConfig("idaRed",room.controller.level)
        return {
            creep:[
                [
                  { Role:"idaRed",
                    body:body.body,
                    isAdapt:true,}
                ,1]],
            team:[]
        }
    }
    public static createPlanOfTeam2(room:Required<Room> ):IWarPlan|undefined
    {
        const redbody = getRoleConfig("idaRed",room.controller.level);
        const healbody = getRoleConfig("idaHeal",room.controller.level);
        const teamconfig:ITeamConfig={
                        type:"Team2",
                        creep:[
                            [
                                {
                                    Role:"idaRed",
                                    body:redbody.body,
                                    isAdapt:true,
                                },
                                1
                            ],
                            [
                                {
                                    Role:"idaHeal",
                                    body:healbody.body,
                                    isAdapt:true,
                                },
                                1
                            ],
                        ]
                    }
        return {
            creep:[
                  ],
            team:[[teamconfig,1]]
        }
    }
     
    /**
     * 正面战斗策略,能在正面战斗击败
     */ 
    public static createPlanOfBattle(room:Required<Room>,enemys:IEnemyTeamSats,maxBoost = 3):IWarPlan|undefined
    {
        if(enemys.attack+enemys.rangeAttack ==0 )
        {
            return this.createPlanOfDestoryStructure(room);
        }
        else if ( room.controller.level<=4  )
        {
            if(enemys.hostileCreeps.some(e=>UtilsHelper.isNPC(e)))
            {
                return this.createPlanOfDestoryStructure(room);
            }
            else 
            {
                return this.createPlanOfTeam2(room);
            }
        }
        const plan  = WarStrategy.battelstrategy.createCreepBodyConfig(enemys,room.energyCapacityAvailable,maxBoost);
        if(plan)
        {
            plan.forEach(e=>e[0].isAdapt=true);
            if(plan.find(e=>e[0].Role == "idaRed") && plan.length>1)
            {
                const creepCount =  plan.reduce((e,a)=>e+a[1],0);
                if(creepCount ==2)
                {
                    return {
                        creep:plan,
                        team:[
                            [{
                                type:"Team2",
                                creep:plan
                            },1]
                        ]
                    }
                }
                if(creepCount ==4)
                {
                    return {
                        creep:plan,
                        team:[
                            [{
                                type:"Team4",
                                creep:plan
                            },1]
                        ]
                    }
                }
            }
            return {
                creep:plan,
                team:[]
            }
        }
        return undefined
    }

    /**
     * 骚扰策略。引开对方的小队。保证自己不死就行的配置
     * @param enemys 
     */
    public static createPlanOfharass(room:Required<Room>,enemys:IEnemyTeamSats)
    {

    }

    
    /**
     * 骚扰策略。引开对方的小队。保证自己不死就行的配置
     * @param enemys 
     */
     public static createPlanOfDefend(room:Required<Room>,enemys:IEnemyTeamSats):IWarPlan 
     {
        return this.defendstrategy.createCreepBodyConfig(enemys,room )
     }

    public static getEnemystatus(hostcreeps:Creep[] ,cachestructures?: CacheDataStructure<ICacheStructure>):IEnemyTeamSats
    {
        let sum_heals = 0;
        let hostiles_damage=0;
        let hostiles_rangeattack=0;
        let EnemyCount=0;
        let max_damage:number=-1;
        if(cachestructures)
        {
            for(const creep of hostcreeps)
            {
                sum_heals+=  BodySetup.GetBodyAbility(HEAL,"heal","heal",creep.body);
                hostiles_rangeattack+=CreepAbilityHelper.getCreepRangeAttackAbility(creep);
                hostiles_damage+=CreepAbilityHelper.getCreepAttackAbility(creep);
                const realDamage = CreepAbilityHelper.GetRealBearDamage(creep,cachestructures.inquireDamage(creep.pos));
                if(max_damage <0)
                {
                    max_damage= realDamage; 
                }
                else if(max_damage < realDamage)
                {
                    max_damage= realDamage;
                }
                if(!UtilsHelper.isNPC(creep))
                {
                    EnemyCount++;
                }
            }
        }
        else
        {
            max_damage=0;
            for(const creep of hostcreeps)
            {
                sum_heals+=  BodySetup.GetBodyAbility(HEAL,"heal","heal",creep.body);
                hostiles_rangeattack+=CreepAbilityHelper.getCreepRangeAttackAbility(creep);
                hostiles_damage+=CreepAbilityHelper.getCreepAttackAbility(creep);
                
                if(!UtilsHelper.isNPC(creep))
                {
                    EnemyCount++;
                }
            }
        }
        
        return {
            heal:sum_heals,         // 敌方单位治疗总量
            max_damage:max_damage,           // 防御塔对敌方造成的最大伤害
            attack:hostiles_damage, // 敌方单位伤害总量
            rangeAttack:hostiles_rangeattack,
            enemyCount:EnemyCount,  // 非NPC的敌方单位数量
            hostileCreeps:hostcreeps, // 敌方的爬
            groupCreeps:   this.classifyEnemy(hostcreeps)
        }
    }
    public static classifyEnemy(enemys:Creep[])
    {
      
        const samples = _.map(enemys,e=>new RoomObjectSample<Creep>(e));
        const groups = DBScan.classify<RoomObjectSample<Creep>>(samples,1,2);

        const armys=_.map(groups.cluster,e=>_.map(Array.from(e),i=>i.Data));
        armys.push(..._.map(groups.left,e=>[e.Data]));
        return armys;
    }
}